﻿using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;

namespace CodeContrib
{
	public static class DataExtensions
	{
		public static string ToCsv<T>(this IEnumerable<T> source)
		{
			return ToCsv(source, ',');
		}

		public static string ToCsv<T>(this IEnumerable<T> source, char separator)
		{
			StringBuilder csv;

			if (source != null)
			{
				csv = new StringBuilder();

				source.ForEach(value => csv.AppendFormat("{0}{1}", value, separator));

				return csv.ToString(0, csv.Length - 1);
			}

			return null;
		}

		public static DataTable ToDataTable<T>(this IEnumerable<T> source, params string[] columnNames)
		{
			var table = new DataTable();

			if (!source.Any())
			{
				return table;
			}

			var objectType = source.First().GetType();

			foreach (var columnName in columnNames)
			{
				foreach (var property in
					objectType.GetProperties().Where(x => x.CanRead && x.GetIndexParameters().Length == 0 && x.Name == columnName))
				{
					var column = table.Columns.Add(property.Name);
					column.ExtendedProperties["Type"] = "P";
					column.DataType = property.PropertyType;
				}

				foreach (var field in objectType.GetFields().Where(x => x.IsPublic && x.Name == columnName))
				{
					var column = table.Columns.Add(field.Name);
					column.ExtendedProperties["Type"] = "F";
					column.DataType = field.FieldType;
				}
			}

			foreach (var item in source)
			{
				var row = table.NewRow();

				foreach (DataColumn column in table.Columns)
				{
					if (column.ExtendedProperties["Type"].ToString() == "F")
					{
						var field = objectType.GetField(column.ColumnName);

						if (field != null)
						{
							row[column.ColumnName] = field.GetValue(item);
						}
					}
					else if (column.ExtendedProperties["Type"].ToString() == "P")
					{
						var property = objectType.GetProperty(column.ColumnName);

						if (property != null)
						{
							row[column.ColumnName] = property.GetValue(item, null);
						}
					}
				}

				table.Rows.Add(row);
			}

			return table;
		}
	}
}